【Python Celery】本番運用時に知っておくべき10のこと 您所在的位置:网站首页 celery bind=true 【Python Celery】本番運用時に知っておくべき10のこと

【Python Celery】本番運用時に知っておくべき10のこと

2023-05-27 00:22| 来源: 网络整理| 查看: 265

Read this article in English 0_1.png

エンジニアのみなさん、ちゃんとセロリ食べてますか?

はじめに

CeleryはPython用の非同期タスク処理を行うためのライブラリです。タスクの同時実行数、ヘルスチェック、ブローカー、再スケジューリングなど、多くの設定項目があります。しかし、ドキュメントが古かったり探しづらかったりするため、最初のうちはうまくいかないことが多々あると思います。

Celeryを使いこなせるようになれば、大量のタスクを効率よく処理できます。この記事では、Celeryを本番環境で運用した経験から学んだことを共有したいと思います。

本番運用時に知っておくべき10のこと 1. ヘルスチェックは inspect ping コマンドを使う

Celeryのワーカーのヘルスチェックは、inspect ping コマンドで行うのがおすすめです。

このコマンドを打つと、Celeryはすべてのワーカーの状態を確認しようとします。ワーカーを複数のノードに分けている場合は、--destination celery@${HOSTNAME} のように、確認対象を絞ると、不要なオーバーヘッドを避けることができます。

celery -A myapp inspect ping --destination celery@${HOSTNAME}

Elastic Beanstalk (EB)、Kubernetes、Elastic Container Service (ECS) などのオーケストレーションツールには、ヘルスチェックの間隔・タイムアウト・リトライ回数を設定できます。Celeryのヘルスチェックは、重い計算でCPU使用率が高くなり、pingコマンドの実行に数秒かかることがあるため、以下のような余裕を持った設定がおすすめです。

項目 設定 interval 30 timeout 15 startPeriod 10 retries 5

CeleryのCPU使用率が高すぎる場合は、--concurrency フラグでタスクの同時実行数を制限するのも効果的です。詳しくは#9を参照してください。

2. Pythonコードからタスクを再実行する方法

ネットワーク接続やレート制限の影響でタスクが失敗した時に、リトライすることが有効な対策です。Pythonコードからタスクをリトライするには、まずタスクデコレーターに bind=True フラグを設定してタスクインスタンスを取得します。タスク関数の中で、raise self.retry(...) で処理を中断して再スケジューリングします。

@app.task(bind=True, max_retries=3) def my_task(self) try: # .. 外部APIを呼ぶなど .. except (ConnectionError, RateLimitExceeded) as e: raise self.retry(exc=e, countdown=retry_delay)

retryメソッドに渡せる引数についてはこちらをご覧ください。

特に本番環境では、発生したエラーの詳細情報を残しておくことが重要なので、self.request.retries でタスクのリトライ回数を記録することをおすすめします。回数を記録することで、デバッグやリトライ回数と間隔の調整がしやすくなります。そして、リトライ回数に応じてログレベルを上げていくことで、エラーの緊急度をより自然に表現できます。

@app.task(bind=True, max_retries=3) def my_task(self) try: # ...call API... except (ConnectionError, RateLimitExceeded) as e: + msg = f"User {user_id} API call failed (retries: {self.request.retries}/3)" + if self.request.retries =t4) 64 64 EC2 (>> group_of_tasks_with_no_return_values.get() [None, None, None, None, None, None, None, None, None, None, ...]

この無意味なデータはブローカーから取得されているので、効率悪いですよね。代わりに waiting() と forget() を使ってみましょう。

終わりに

Celeryは素晴らしいフレームワークですが、設定項目が多くてコツを掴むまで時間がかかります。この記事では、ヘルスチェック、タスクの再スケジューリング、プリフェッチするタスク数の制限、ブローカーの選択など、主に本番環境での運用経験から学んできたことを説明しました。Celeryキューの分割方法やタスクのプライオリティ(優先度)の設定など、触れていないトピックもあるので網羅的なリストではないですが、少しでもお役に立てれば幸いです。

Celeryメンテナはちょっとしたドキュメント修正も歓迎するので、ぜひOSS貢献を検討してください。

その他参考になる情報 OpenTelemetryで分散型アプリケーション の処理フローを可視化する A complete guide to production-ready Celery configuration Python Celery Best Practices - Tips and tricks to help you build scalable distributed apps with Celery Configure Celery for reliable delivery Why You Should use Celery with RabbitMQ Automatically Retrying Failed Celery Tasks Graceful shutdowns with ECS Tutorial: Test Spot Instance interruptions using AWS FIS How do I handle Spot termination notices in AWS Fargate Spot tasks?


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有